#import "CTSuperPlayerModel.h"
#import "SPPlayCGIParser.h"
#import "CTSuperPlayerModelInternal.h"
#import "CTSuperPlayerDefines.h"

#if __has_include(<AFHTTPSessionManager.h>)
#import <AFHTTPSessionManager.h>
#elif __has_include("AFHTTPSessionManager.h")
#import "AFHTTPSessionManager.h"
#endif

@implementation CTSuperPlayerVideoId
@end

#pragma mark -

@implementation CTSuperPlayerVideoIdV2
@end

#pragma mark -

@implementation CTSuperPlayerModel

- (instancetype)init {
    self = [super init];
    if (self) {
        _sessionManager = [AFHTTPSessionManager manager];
        _defaultPlayIndex = NSUIntegerMax;
    }
    return self;
}

- (void)dealloc {
    [_sessionManager invalidateSessionCancelingTasks:YES resetSession:YES];
}

- (NSString *)playingDefinitionUrl
{
    NSString *url;
    for (int i = 0; i < self.multiVideoURLs.count; i++) {
        if ([self.multiVideoURLs[i].title isEqualToString:self.playingDefinition]) {
            url = self.multiVideoURLs[i].url;
        }
    }
    if (url == nil) url = self.videoURL;
    if (url == nil) {
        if (self.multiVideoURLs.count > 0) url = self.multiVideoURLs.firstObject.url;
    }
    return url;
}

- (void)setDefaultPlayIndex:(NSUInteger)defaultPlayIndex {
    _defaultPlayIndex = defaultPlayIndex;
    if (defaultPlayIndex < _multiVideoURLs.count) {
        self.playingDefinition = _multiVideoURLs[defaultPlayIndex].title;
    }
}

- (void)setMultiVideoURLs:(NSArray<CTSuperPlayerUrl *> *)multiVideoURLs {
    _multiVideoURLs = multiVideoURLs;
    if (_defaultPlayIndex < multiVideoURLs.count) {
        self.playingDefinition = _multiVideoURLs[_defaultPlayIndex].title;
    }
}

- (NSArray *)playDefinitions
{
    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:self.multiVideoURLs.count];
    for (CTSuperPlayerUrl *url in self.multiVideoURLs) {
        [array addObject:url.title];
    }
    return array;
}

- (NSInteger)playingDefinitionIndex
{
    for (int i = 0; i < self.multiVideoURLs.count; i++) {
        if ([self.multiVideoURLs[i].title isEqualToString:self.playingDefinition]) {
            return i;
        }
    }
    return 0;
}

- (NSURLSessionTask *)requestWithCompletion:(void (^)(NSError *, CTSuperPlayerModel *model))completion
{
    AFHTTPSessionManager *manager = self.sessionManager;
    int ver = self.videoId ? 4 : 2;
    NSString *url = [NSString stringWithFormat:@"https://%@/getplayinfo/v%d/%ld/%@",
                     kPlayCGIHostName, ver, self.appId, self.videoId ? self.videoId.fileId : self.videoIdV2.fileId];

    // 防盗链参数
    NSDictionary *params = [self m_buildParams];

    __weak CTSuperPlayerModel *weakSelf = self;
    return [manager GET:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
        __strong CTSuperPlayerModel *strongSelf = weakSelf;
#if DEBUG
        NSLog(@"%@", responseObject);
#endif
        NSInteger code = [responseObject[@"code"] integerValue];
        if (code != 0) {
            NSString *msg = responseObject[@"message"];
            NSString *requestID = responseObject[@"requestId"];
            NSString *warning = responseObject[@"warning"];
            NSError *error = [NSError errorWithDomain:@"CTSuperPlayerCGI"
                                                 code:code
                                             userInfo:@{ NSLocalizedDescriptionKey: msg,
                                                         @"requestID": requestID ? : @"",
                                                         @"warning": warning ? : @"" }];
            if (completion) {
                completion(error, strongSelf);
                return;
            }
            return;
        }

        NSInteger responseVersion = [responseObject[@"version"] integerValue];
        if (responseVersion == 0) {
            responseVersion = 2;
        }
        Class<SPPlayCGIParserProtocol> parser = [SPPlayCGIParser parserOfVersion:responseVersion];
        SPPlayCGIParseResult *result = [parser parseResponse:responseObject];

        strongSelf.videoURL = result.url;
        strongSelf.multiVideoURLs = result.multiVideoURLs;
        strongSelf.keyFrameDescList = result.keyFrameDescList;
        strongSelf.imageSprite = result.imageSprite;
        if (responseVersion == 4) {
            strongSelf.originalDuration = result.originalDuration;
        }
        if (completion) {
            completion(nil, strongSelf);
        }
    } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
        __strong CTSuperPlayerModel *strongSelf = weakSelf;
        if (error.code != NSURLErrorCancelled) {
            if (completion) {
                completion(error, strongSelf);
            }
        }
    }];
}

- (NSDictionary *)m_buildParams {
    NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithCapacity:1];
    if (self.videoId) {
        if (self.videoId.psign) {
            params[@"psign"] = self.videoId.psign;
        }
    } else if (self.videoIdV2) {
        if (self.videoIdV2.timeout) {
            params[@"t"] = self.videoIdV2.timeout;
        }
        if (self.videoIdV2.us) {
            params[@"us"] = self.videoIdV2.us;
        }
        if (self.videoIdV2.sign) {
            params[@"sign"] = self.videoIdV2.sign;
        }
        if (self.videoIdV2.exper >= 0) {
            params[@"exper"] = @(self.videoIdV2.exper);
        }
    }
    return params;
}

+ (instancetype)playerModelWithUrl:(NSString *)url {
    CTSuperPlayerModel *model = [CTSuperPlayerModel new];
    model.videoURL = url;
    return model;
}

@end
